DEFINITION MODULE fxEventTasks; (* Franz Kronseder / ETHZ / 02.08.85 *)
                                (* last modified 09.08.85 *)
 (* a simple scheduler intended to allow arranging  a Modula-2 *)
 (* program on Macintosh  as a collection of Event handling    *)
 (* subroutines *)

 (* this module is conceptually built on top of the Macintosh *)
 (* Toolbox Event Manager and its main goal is to support the *)
 (* decomposition of an otherwise tremenduously large CASE-statement *)
 (* for event handling into independent modules *)
 (* from Inside Macintosh: ABOUT THE TOOLBOX EVENT MANAGER: *)
 (* "A typical Macintosh application program is event-driven: It decides *)
 (* what to do from moment to moment by asking the Event Manager for *)
 (* events and responding to them one by one in whatever way is *)
 (* appropriate."  *)

IMPORT MacBase,EventMgr;
EXPORT QUALIFIED
 everyEvent,nullEvent,mouseDown,mouseUp,keyDown,keyUp,autoKey,updateEvt,
 diskEvt,activateEvt,abortEvt,reserveEvt,driverEvt,
 app1Evt,app2Evt,app3Evt,app4Evt,
 optionKey,alphaLock,ShiftKey,CmdKey,BtnState,activeFlag,changeFlag,

 NoErr,OsErr,EventRecord,EventHandler,TaskProc,
 TaskPtr,TaskDefRec,defaultTask,
 pushTask,popTask,popallTasks,
 AbortCode,NoAbort,abortEvtFound,
 PollEventTasks,GetBusyReadEvent,ErrorText;
		
(*------ from EventMgr.def----------------
  EventRecord = RECORD
                  what:      INTEGER;
                  CASE BOOLEAN  OF
                    TRUE : message: LongInt;
                  | FALSE: msgchar: ARRAY [0..3] OF CHAR;
                  END;
                  when:      LongInt;
                  where:     Point;
                  CASE BOOLEAN OF
                    TRUE : modifiers: BITSET;
                  | FALSE: modifwrd : CARDINAL; (* modifier word *)
                  END;
                END;  (* record *)
------ from EventMgr.def----------------*)

CONST NoErr = 0; (* ok value for OsErr *)
      NoAbort = 0; (* for AbortCode *)

CONST
  everyEvent  = EventMgr.everyEvent  ;
  nullEvent   = EventMgr.nullEvent   ; mouseDown  = EventMgr.mouseDown;
  mouseUp     = EventMgr.mouseUp     ; keyDown    = EventMgr.keyDown;
  keyUp       = EventMgr.keyUp       ; autoKey    = EventMgr.autoKey;
  updateEvt   = EventMgr.updateEvt   ; diskEvt    = EventMgr.diskEvt;
  activateEvt = EventMgr.activateEvt ; abortEvt   = EventMgr.abortEvt;
  reserveEvt  = EventMgr.reserveEvt  ; driverEvt  = EventMgr.driverEvt;
  app1Evt     = EventMgr.app1Evt     ; app2Evt    = EventMgr.app2Evt;
  app3Evt     = EventMgr.app3Evt     ; app4Evt    = EventMgr.app4Evt;

  (* modifiers !!! here Bitnumbers in BITSET !!! *)
  optionKey = EventMgr.optionKey; (*2048, Bit 3 of high byte  *)
  alphaLock = EventMgr.alphaLock; (*1024, Bit 2  *)
  ShiftKey  = EventMgr.ShiftKey;  (* 512, Bit 1  *)
  CmdKey    = EventMgr.CmdKey;    (* 256, Bit 0  *)
  BtnState  = EventMgr.BtnState;  (* 128, Bit 7 of low byte is mouse button state  *)
  activeFlag= EventMgr.activeFlag;(*   1, bit 0 of modifiers for activate event  *)
  changeFlag= EventMgr.changeFlag;(*   2, bit 1 of modifiers for activate event  *)


TYPE OsErr = MacBase.OsErr; LongInt = MacBase.LongInt;
     EventRecord = EventMgr.EventRecord;
     EventHandler = PROCEDURE (VAR EventRecord):BOOLEAN;
                    (* this procedure type is used by the scheduler for *)
                    (* distributing events obtained by GetNextEvent *)
                    (* to the activated tasks *)
                    (* the EventHandler first has to analyse the event, *)
                    (* then either handle it and return TRUE or not *)
                    (* handle it and return FALSE  *)
                    (* EventHandler(NIL) is a legal value *)

     TaskProc = PROCEDURE ():OsErr;
                (* this procedure type is used for specifying the *)
                (* initialization, termination and periodic activities *)
                (* attributed to a task *)
                (* TaskProc(NIL) is a legal value *)

     TaskPtr = POINTER TO TaskDefRec;
     TaskDefRec = RECORD (* Task Definition Record *)
                  SetupProc  : TaskProc;    (* alloc and init task data *)
                  EventProc  : EventHandler;(* check and treat Events *)
                  CleanupProc: TaskProc;    (* cleanup and dealloc task data *)
                  IdleProc:    TaskProc;    (* periodic action between Events *)

                  TaskError  : OsErr;       (* some associated data *)
                  TaskEnabled: BOOLEAN;     (* EventHandler on/off switch*)
                  RefCon     : LongInt;     (* 32 bits of User Data *)
                 END; (*record*)
      (* The variables of type TaskDefRec must be supplied by the      *)
      (* task defining modules and contain valid data during the whole *)
      (* lifetime of the task, not just during initialisation          *)
      (* fxEventTasks maintains only an array of TaskPtrs to such *)
      (* TaskDefRecs *)
(*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
VAR AbortCode : INTEGER;  (* for signalling occurence of abort events *)

PROCEDURE abortEvtFound():BOOLEAN;
 (* returns true, iff AbortCode <> 0 *)

PROCEDURE pushTask(Task:TaskPtr):OsErr;
 (* push Task onto the scheduler and activate it *)
 (* by executing its SetupProc *)

PROCEDURE popTask(VAR Task:TaskPtr):OsErr;
 (* pop a Task from the scheduler and deactivate it by *)
 (* executing its CleanupProc *)

PROCEDURE popallTasks():OsErr;
 (* deactivate and remove all entries in the Task scheduler *)

PROCEDURE PollEventTasks;
 (* to be called repeatedly in the Main Loop of a Program    *)
 (* PollEventTasks performs an EventMgr.GetNextEvent;        *)
 (* distrubutes Events to the activated EventHandler;        *)
 (* runs through activated IdleProcs if no Events available. *)
 (* keyDown or AutoKey events that remain unhandled by the tasks *)
 (* are buffered for GetBusyReadEvent which is for use by MODULE *)
 (* Terminal. unhandled abortEvt are flagged in the AbortCode *)
 (* variable *)

PROCEDURE defaultTask(VAR Task:TaskPtr);
 (* IF Task=NIL then return pointer to internal default task *)
 (* otherwise copy values of internal default task to Task^  *)

PROCEDURE GetBusyReadEvent(VAR event:EventRecord):BOOLEAN;
 (* get keyDown and autoKey events that no active Task wanted to handle. *)
 (* this enables the Module Terminal to run as lowest priority handler   *)

PROCEDURE ErrorText(error:OsErr; VAR text:ARRAY OF CHAR);
 (* return error message for a given errorcode *)
 (* not yet implemented, returns empty modula strings sofar *)

END fxEventTasks.
